package com.cskaoyan.javase.oop3._1interface._1basic;

/**
 * 接口的特点:
 * 接口的特点我们主要研究以下方面
 * 接口的语法:
 * [访问权限修饰符] interface 接口名{}
 *
 * 接口的声明特点:
 *      接口是不能创建对象的,接口是抽象的,接口的修饰符列表中隐含了关键字abstract
 *      接口的声明中是不能存在final的,接口天生就是为了被实现的
 *
 * 接口的实现类的书写格式:
 *      使用"implements"关键字,一个类可以实现多个接口
 *      在实际开发中,在写接口实现类时,推荐在接口这个包下
 *      写一个包,叫"impl",然后在其中写实现类,命名为:
 *          "接口名Impl"
 *          表示它是一个接口的实现类
 *
 * 成员特点
 *      普通成员变量:没有
 *      静态成员变量:没有
 *      接口中的变量默认都是"public static final"修饰的全局常量
 *          并且访问权限修饰符一定是public是不可用被更改的
 *          注:
 *              1.实际上接口中所有能定义的结构都一定是public修饰的
 *              2.接口中全局常量的赋值一定是显式赋值的,因为接口没有静态代码块
 *              3.实际开发中,接口当中,99%的情况下是不应该写变量的,除非:
 *                  接口的所有实现类中都需要使用这个常量,可以放进接口中
 *          接口中绝大多数情况下,都只会定义方法,没有变量的定义.
 *
 *      普通/静态成员方法:没有,接口中没有普通成员方法,也没有静态成员方法.
 *      接口中的方法,直到Java8之前,只有抽象方法,方法的声明中,隐含关键字:"public abstract" 都是公共的抽象方法
 *          隐含关键字没必要写出来,建议写抽象方法时,直接写:
 *             返回值类型 方法名(形参列表);
 *          接口表示功能扩展,绝大多数情况下,接口都非常简洁,只有抽象方法的声明.
 *
 *    而到了Java8中,接口中允许定义具有方法体的实现方法,那就是接口中的:
 *       1.默认方法
 *          语法:
 *          default 返回值类型 方法名(形参列表){
 *              // 方法体
 *          }
 *          注:访问权限修饰符默认public,不可更改
 *          使用:
 *             接口的实现类对象可以调用该方法
 *             而且由于这个方法不是抽象方法,不需要子类实现
 *                当然子类可以重写!
 *          总的来说,虽然有这种语法,但是尽量不要使用.
 *
 *       2.静态方法
 *          语法:
 *          static 返回值类型 方法名(形参列表){
 *             // 方法体
 *          }
 *          注:访问权限修饰符默认public,不可更改
 *          接口中的静态方法只能用接口名点调用,不能用实现类的类名调用.
 *
 *      构造器
 *          思考: 接口有没有构造器?
 *          接口中没有构造器,因为自己用不上,子类也用不上
 *             因为接口没有成员变量,只有常量
 *             无需使用构造器赋值
 *
 *      代码块
 *          没有构造器,就没有构造代码块
 *          当然接口中也没有静态代码块
 *
 * 以上,总结,接口是不同于类的,实际上它的成员比类要更加简洁:
 *       1.变量:没有变量,只有全局常量,但是很少定义
 *       2.方法:都是抽象方法.虽然Java8中有实现方法,但很少用.
 *       3.代码块:没有
 *       4.构造器:没有
 *
 *
 * 接口的使用,接口的实现类,也就是接口的子类:
 *       1.普通类,必须实现接口中的所有抽象方法
 *       2.抽象类,并且不需要实现接口的抽象方法
 *          当然也可以选择某个或者某几个实现
 *
 *
 * 总结:
 *       接口和类之间的继承(extends)关系
 *       和实现(implements)关系
 *
 *  1.继承:
 *       a.首先继承可以发生在两个类之间
 *       b.继承不能发生在类和接口之间
 *       b.继承可以发生在两个接口之间
 *       总结:继承是不能跨越种族的
 *       并且:
 *          类的继承是单继承的
 *          接口的继承是多继承的
 *
 *  2.实现:
 *      实现仅发生在接口和类之间
 *      而且是类实现接口,接口不能实现类
 *      如果一个类同时发生继承和实现,那么先继承后实现
 *
 *
 *
 *
 *
 *
 *
 * @since 15:12
 * @author wuguidong@cskaoyan.onaliyun.com
 */
// Modifier 'abstract' is redundant for interfaces
public interface IDemo {
   /*
        接口中只能定义public修饰的全局常量
        并且一定要显式赋值
        public static final都是隐含的
        如果确有必要定义全局常量
        请直接写:
            数据类型 常量名 = 值;
    */
   int NUM = 10;

   /*
      接口中的抽象方法
    */
   void test();
   int test2(int a);

   /*
      定义Java8中的实现方法
    */
   default void testDefault(){
      System.out.println("接口中的默认实现方法");
   }

   static void testStatic() {
      System.out.println("接口中的静态实现方法");
   }

}

// 以后开发中常见的接口形式
interface IA{
   void test();
   int test2();
   String test3(double a);
}
abstract class AbstractA implements IA{
}
class IAImpl implements IA{
   @Override
   public void test() {
   }
   @Override
   public int test2() {
      return 0;
   }
   @Override
   public String test3(double a) {
      return null;
   }
}
interface IB{}
interface IC{}
interface ID{}
interface ITest extends IB,IC,ID{}